home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / bootmenu.zip / BOOTMENU.C next >
C/C++ Source or Header  |  1994-02-16  |  5KB  |  195 lines

  1. /*
  2.  * BOOTMENU: a DOS Startup menu that automatically reloads with
  3.  * different AUTOEXEC.BAT and CONFIG.SYS if necessary.
  4.  *
  5.  * Copyright 1992 Dave Dunfield
  6.  * All rights reserved.
  7.  *
  8.  * Permission granted to use for personal (non-commercial) use only.
  9.  */
  10. #include <stdio.h>        /* Standard I/O definitions */
  11. #include <window.h>        /* Windowing library definitions */
  12.  
  13. #define    MAXCFG    10        /* Maximum number of menu entries supported */
  14.  
  15. char description[MAXCFG][71], autoexec[MAXCFG][51], config[MAXCFG][51],
  16.     old_autoexec[51], old_config[51], *parse_ptr, reboot = 0, *boot_dir;
  17.  
  18. unsigned cfg_count = 0, max_length = 0, select = 0, timer = 10;
  19.  
  20. /*
  21.  * Parse a string delimited by '|' from the input line
  22.  */
  23. parse(dest)
  24.     char *dest;
  25. {
  26.     while(isspace(*parse_ptr))
  27.         ++parse_ptr;
  28.     while(*parse_ptr) {
  29.         if((*dest = *parse_ptr++) == '|')
  30.             break;
  31.         ++dest; }
  32.     *dest = 0;
  33. }
  34.  
  35. /*
  36.  * Main program - check if in "reboot phase", and if so, terminate with
  37.  * proper error code. Otherwise, give menu of available options.
  38.  */
  39. main(argc, argv)
  40.     int argc;
  41.     char *argv[];
  42. {
  43.     unsigned i, j, s, s1;
  44.     char buffer[150], buffer1[50];
  45.     FILE *fp;
  46.  
  47.     if(argc > 1)        /* Directory is specified */
  48.         boot_dir = argv[1];
  49.     else {                /* Use directory from program name */
  50.         boot_dir = argv[i=j=0];
  51.         while(s = boot_dir[i]) {
  52.             if(s == '\\')
  53.                 j = i;
  54.             ++i; }
  55.         boot_dir[j] = 0; }
  56.  
  57.     /* If re-booting to establish configuration */
  58.     sprintf(buffer, "%s\\BOOTMENU.CTL", boot_dir);
  59.     if(fp = fopen(buffer, "rv")) {
  60.         fgets(buffer, sizeof(buffer)-1, fp);
  61.         fgets(old_autoexec, sizeof(old_autoexec)-1, fp);
  62.         fgets(old_config, sizeof(old_config)-1, fp);
  63.         fclose(fp);
  64.         select = atoi(buffer+1);
  65.         if(*buffer == '*')
  66.             goto xboot; }
  67.  
  68.     /* Read in configuration directory file */
  69.     sprintf(buffer,"%s\\BOOTMENU.CFG", boot_dir);
  70.     fp = fopen(buffer, "rvq");
  71.     parse_ptr = fgets(buffer, sizeof(buffer)-1, fp);
  72.     parse(buffer1);
  73.     if(*buffer1)
  74.         timer = atoi(buffer1);
  75.     parse(buffer1);
  76.     if(*buffer1)
  77.         select = atoi(buffer1);
  78.     while(parse_ptr = fgets(buffer, sizeof(buffer)-1, fp)) {
  79.         parse(description[cfg_count]);
  80.         parse(autoexec[cfg_count]);
  81.         parse(config[cfg_count]);
  82.         max_length = max(max_length, strlen(description[cfg_count]));
  83.         ++cfg_count; }
  84.     fclose(fp);
  85.  
  86.     /* Open window & indicate available options */
  87.     wopen(40-(max_length+8)/2, 12-(cfg_count+3)/2, max_length+8, cfg_count+3,
  88.         WSAVE|WBOX1|WCOPEN|0x70);
  89.     wcursor_off();
  90.     for(i=0; i < cfg_count; ++i) {
  91.         wprintf("%c%u - %s\n", (i == select) ? '*' : ' ', i, description[i]); }
  92.  
  93.     wprintf("Select: %u", timer);
  94.  
  95.     /* Wait for user to choose selection, or timeout */
  96.     get_time(&j, &j, &s);
  97.     do {
  98.         if(i = wtstc()) {
  99.             if((i == '\n') || (i == ' ') || (i == 0x1B))
  100.                 break;
  101.             if((i - '0') < cfg_count) {
  102.                 select = i - '0';
  103.                 break; } }
  104.         get_time(&j, &j, &s1);
  105.         if(s != s1) {
  106.             s = s1;
  107.             wprintf("\rSelect: %u ", --timer); } }
  108.     while(timer && (i != ' ') && (i != '\n'));
  109.     wclose();
  110.  
  111.     /* If new config uses a different AUTOEXEC, copy it over */
  112.     parse_ptr = autoexec[select];
  113.     if(*parse_ptr && strcmp(parse_ptr, old_autoexec)) {
  114.         strcpy(old_autoexec, parse_ptr);
  115.         copy_files("\\AUTOEXEC.BAT", parse_ptr); }
  116.  
  117.     /* If new config uses a different CONFIG, copy it over */
  118.     parse_ptr = config[select];
  119.     if(*parse_ptr && strcmp(parse_ptr, old_config)) {
  120.         strcpy(old_config, parse_ptr);
  121.         copy_files("\\CONFIG.SYS", parse_ptr); }
  122.  
  123. xboot:
  124.  
  125.     /* Rewrite control file to reflect current state */
  126.     sprintf(buffer, "%s\\BOOTMENU.CTL", boot_dir);
  127.     fp = fopen(buffer, "wvq");
  128.     fprintf(fp,"%c%u\n%s\n%s", reboot ? '*' : '-', select, old_autoexec, old_config);
  129.     fclose(fp);
  130.  
  131.     /* If files have changed - REBOOT! */
  132.     if(reboot) asm {
  133.         MOV        AH,0Dh                    ; Disk RESET function
  134.         INT        21h                        ; Ask DOS
  135.         MOV        AX,40h                    ; BIOS data area
  136.         MOV        ES,AX                    ; Set ES
  137.         MOV        WORD PTR ES:72h,1234h    ; Indicate warm start
  138.         DB        0EAh,0,0,0FFh,0FFh        ; JMP FAR FFFF:0
  139.     }
  140.  
  141.     /* Pass back selection number as errorlevel */
  142.     exit(select);
  143. }
  144.  
  145. /*
  146.  * Copy one or more files from our directory to the destination
  147.  */
  148. copy_files(dest, source)
  149.     char *dest, *source;
  150. {
  151.     char buffer[150], name[15], *ptr, data_flag;
  152.     FILE *fpd, *fps;
  153.  
  154.     fpd = fopen(dest, "wvq");
  155.  
  156.     /* Copy files(s) into output file */
  157.     while(*source) {
  158.         data_flag = 0;
  159.         /* Concatinate directory and source file */
  160.         dest = buffer;
  161.         ptr = boot_dir;
  162.         while(*dest = *ptr++)
  163.             ++dest;
  164.         *dest++ = '\\';
  165.         if(*source == '!') {            /* From general file */
  166.             strcpy(dest, "BOOTMENU.DAT");
  167.             dest = name;
  168.             data_flag = -1; }
  169.         while(*source) {                /* Copy in file name */
  170.             if((*dest = *source++) == ',')
  171.                 break;
  172.             ++dest; }
  173.         *dest = 0;
  174.         /* Copy data into new file */
  175.         fps = fopen(buffer, "rvq");
  176.         if(data_flag) {                    /* Copy from general file */
  177.             while(fgets(buffer, sizeof(buffer)-1, fps)) {
  178.                 if(*buffer == '!') {
  179.                     if(!data_flag)
  180.                         break;
  181.                     if(!strcmp(buffer, name))
  182.                         data_flag = 0; }
  183.                 else if(!data_flag) {
  184.                     fputs(buffer, fpd);
  185.                     putc('\n', fpd); } } }
  186.         else {                            /* Copy from separate file */
  187.             while(fgets(buffer, sizeof(buffer)-1, fps)) {
  188.                 fputs(buffer, fpd);
  189.                 putc('\n', fpd); } }
  190.         fclose(fps); }
  191.  
  192.     fclose(fpd);
  193.     reboot = -1;
  194. }
  195.